package com.ttg.utils;

//~--- non-JDK imports --------------------------------------------------------

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.security.InvalidParameterException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

//~--- JDK imports ------------------------------------------------------------

//~--- classes ----------------------------------------------------------------

/**
 * Class DateUtil
 * Description
 * Create 2016-02-25 01:00:56
 * @author Ardy
 */
public class DateUtil extends DateUtils {

    /**
     * Field dtLong
     * Description
     */
    public static final String dtLong = "yyyyMMddHHmmss";

    /**
     * Field simple
     * Description
     */
    public static final String simple = "yyyy-MM-dd HH:mm:ss";

    /**
     * Field dtShort
     * Description
     */
    public static final String dtShort = "yyyyMMdd";

    /** 
     * Field parsePatterns
     * Description 
     */
    private static String[] parsePatterns = {
        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"
    };

    /**
     * Method date2Str
     * Description 说明：
     *
     * @param date 说明：
     *
     * @return 返回值说明：
     */
    public static String date2Str(Date date) {
        return date2Str(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     *
     * @return 返回值说明：
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     *
     * @param pattern 说明：
     *
     * @return 返回值说明：
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>();
    private static final Object object = new Object();

    public static Date addYears(Date date, int amount)
    {
        return DateUtils.addYears(date, amount);
    }

    public static Date addMonths(Date date, int amount)
    {
        return DateUtils.addMonths(date, amount);
    }

    public static Date addWeeks(Date date, int amount)
    {
        return DateUtils.addWeeks(date, amount);
    }

    public static Date addDays(Date date, int amount)
    {
        return DateUtils.addDays(date, amount);
    }

    public static Date addHours(Date date, int amount)
    {
        return DateUtils.addHours(date, amount);
    }

    public static Date addMinutes(Date date, int amount)
    {
        return DateUtils.addMinutes(date, amount);
    }

    public static Date addSeconds(Date date, int amount)
    {
        return DateUtils.addSeconds(date, amount);
    }

    public static Date addMilliseconds(Date date, int amount)
    {
        return DateUtils.addMilliseconds(date, amount);
    }

    public static Date truncate(Date date, int field)
    {
        return DateUtils.truncate(date, field);
    }

    public static String formatDate(Date date){
        return DateFormatUtils.format(date,dtShort);
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     *
     * @param date 说明：
     * @param pattern 说明：
     *
     * @return 返回值说明：
     */
    public static String formatDate(Date date, Object ... pattern) {
        String formatDate = null;

        if ((pattern != null) && (pattern.length > 0)) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }

        return formatDate;
    }

    /**
     * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
     *
     * @param date 说明：
     *
     * @return 返回值说明：
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前时间字符串 格式（HH:mm:ss）
     *
     * @return 返回值说明：
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
     *
     * @return 返回值说明：
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     *
     * @return 返回值说明：
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式（MM）
     *
     * @return 返回值说明：
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式（dd）
     *
     * @return 返回值说明：
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串 格式（E）星期几
     *
     * @return 返回值说明：
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 日期型字符串转化为日期 格式
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     *   "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" }
     *
     * @param str 说明：
     *
     * @return 返回值说明：
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }

        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = new Date().getTime() - date.getTime();

        return t / ( 24 * 60 * 60 * 1000 );
    }

    /**
     * Method getDateStart 
     * Description 说明：
     *
     * @param date 说明：
     *
     * @return 返回值说明：
     */
    public static Date getDateStart(Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    /**
     * Method getDateEnd 
     * Description 说明：
     *
     * @param date 说明：
     *
     * @return 返回值说明：
     */
    public static Date getDateEnd(Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    /**
     * 判断字符串是否是日期
     * @param timeString
     * @return
     */
    public static boolean isDate(String timeString) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        format.setLenient(false);

        try {
            format.parse(timeString);
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    /**
     * 格式化时间
     * @param timestamp
     * @return
     */
    public static String dateFormat(Date timestamp) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        return format.format(timestamp);
    }

    /**
     * 获取系统时间Timestamp
     * @return
     */
    public static Timestamp getSysTimestamp() {
        return new Timestamp(new Date().getTime());
    }

    /**
     * 获取系统时间Date
     * @return
     */
    public static Date getSysDate() {
        return new Date();
    }

    /**
     * 生成时间随机数
     * @return
     */
    public static String getDateRandom() {
        String s = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());

        return s;
    }

    /**
     * Method date2Str
     * Description 说明：
     *
     * @param date 说明：
     * @param format 说明：
     *
     * @return 返回值说明：
     */
    public static String date2Str(Date date, String format) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);

            return sdf.format(date);
        } else {
            return "";
        }
    }

    /**
     * Method getOrderNum
     * Description 说明：
     *
     * @return 返回值说明：
     */
    public static String getOrderNum() {
        Date       date = new Date();
        DateFormat df   = new SimpleDateFormat(dtLong);

        return df.format(date);
    }

    /**
     * Method getDateFormatter
     * Description 说明：
     *
     * @return 返回值说明：
     */
    public static String getDateFormatter() {
        Date       date = new Date();
        DateFormat df   = new SimpleDateFormat(simple);

        return df.format(date);
    }

    /**
     * Method getThree
     * Description 说明：
     *
     * @return 返回值说明：
     */
    public static String getThree() {
        Random rad = new Random();

        return rad.nextInt(1000) + "";
    }
    public static int intervalYears(Date beginDate, Date endDate)
    {
        if (beginDate.after(endDate)) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }

        int endDateYear = getYear(endDate);
        int beginDateYear = getYear(beginDate);

        int interval = endDateYear - beginDateYear;

        return interval;
    }
    /**
     * 将日期转化为日期字符串。失败返回null。
     *
     * @param date
     *            日期
     * @param dateStyle
     *            日期风格
     * @return 日期字符串
     */
    public static String dateToString(Date date, DateStyle dateStyle) {
        String dateString = null;
        if (dateStyle != null) {
            dateString = dateToString(date, dateStyle.getValue());
        }
        return dateString;
    }

    /**
     * 将日期转化为日期字符串。失败返回null。
     *
     * @param date
     *            日期
     * @param pattern
     *            日期格式
     * @return 日期字符串
     */
    public static String dateToString(Date date, String pattern) {
        String dateString = null;
        if (date != null) {
            try {
                dateString = getDateFormat(pattern).format(date);
            } catch (Exception e) {
            }
        }
        return dateString;
    }

    /**
     * 获取SimpleDateFormat
     *
     * @param pattern
     *            日期格式
     * @return SimpleDateFormat对象
     * @throws RuntimeException
     *             异常：非法日期格式
     */
    private static SimpleDateFormat getDateFormat(String pattern)
            throws RuntimeException {
        SimpleDateFormat dateFormat = threadLocal.get();
        if (dateFormat == null) {
            synchronized (object) {
                if (dateFormat == null) {
                    dateFormat = new SimpleDateFormat(pattern);
                    dateFormat.setLenient(false);
                    threadLocal.set(dateFormat);
                }
            }
        }
        dateFormat.applyPattern(pattern);
        return dateFormat;
    }

    /**
     * 日期格式枚举类
     *
     *
     * @author liyanxiong
     *
     * @date 2015-4-29下午2:13:44
     */
    public enum DateStyle {

        YYYY_MM("yyyy-MM", false),

        YYYY_MM_DD("yyyy-MM-dd", false),

        YYYYMMDD("yyyyMMdd", false),

        YYYY_MM_DD_HH_MM("yyyy-MM-dd HH:mm", false),

        YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss", false),

        YYYYMMDDHHMMSS("yyyyMMddHHmmss", false),

        YYYY_MM_EN("yyyy/MM", false),

        YYYY_MM_DD_EN("yyyy/MM/dd", false),

        YYYY_MM_DD_HH_MM_EN("yyyy/MM/dd HH:mm", false),

        YYYY_MM_DD_HH_MM_SS_EN("yyyy/MM/dd HH:mm:ss", false),

        YYYY_MM_CN("yyyy年MM月", false),

        YYYY_MM_DD_CN("yyyy年MM月dd日", false),

        YYYY_MM_DD_HH_MM_CN("yyyy年MM月dd日 HH:mm", false),

        YYYY_MM_DD_HH_MM_SS_CN("yyyy年MM月dd日 HH:mm:ss", false),

        HH_MM("HH:mm", true),

        HH_MM_SS("HH:mm:ss", true),

        MM_DD("MM-dd", true),

        MM_DD_HH_MM("MM-dd HH:mm", true),

        MM_DD_HH_MM_SS("MM-dd HH:mm:ss", true),

        MM_DD_EN("MM/dd", true),

        MM_DD_HH_MM_EN("MM/dd HH:mm", true),

        MM_DD_HH_MM_SS_EN("MM/dd HH:mm:ss", true),

        MM_DD_CN("MM月dd日", true),

        MM_DD_HH_MM_CN("MM月dd日 HH:mm", true),

        MM_DD_HH_MM_SS_CN("MM月dd日 HH:mm:ss", true);

        private String value;

        private boolean isShowOnly;

        DateStyle(String value, boolean isShowOnly) {
            this.value = value;
            this.isShowOnly = isShowOnly;
        }

        public String getValue() {
            return value;
        }

        public boolean isShowOnly() {
            return isShowOnly;
        }
    }



    public static int intervalMonths(Date beginDate, Date endDate)
    {
        if (beginDate.after(endDate)) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }

        int endDateYear = getYear(endDate);
        int beginDateYear = getYear(beginDate);

        int intervalYear = endDateYear - beginDateYear;

        int endDateMonth = getMonth(endDate);
        int beginDateMonth = getMonth(beginDate);

        int intervalMonth = 0;
        if (endDateMonth < beginDateMonth) {
            --intervalYear;
            intervalMonth = endDateMonth + 12 - beginDateMonth;
        } else {
            intervalMonth = endDateMonth - beginDateMonth;
        }

        return (intervalYear * 12 + intervalMonth);
    }

    public static int intervalDays(Date beginDate, Date endDate)
    {
        if (beginDate.after(endDate)) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }

        beginDate = truncate(beginDate, 5);
        endDate = truncate(endDate, 5);

        long interval = endDate.getTime() - beginDate.getTime();

        return (int)(interval / 86400000L);
    }

    public static int intervalHours(Date beginDate, Date endDate)
    {
        if (beginDate.after(endDate)) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }

        beginDate = truncate(beginDate, 10);
        endDate = truncate(endDate, 10);

        long interval = endDate.getTime() - beginDate.getTime();

        return (int)(interval / 3600000L);
    }

    public static int intervalMinutes(Date beginDate, Date endDate)
    {
        if (beginDate.after(endDate)) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }
        return getIntervalMinutes(beginDate, endDate);
    }

    public static int getIntervalMinutes(Date beginDate, Date endDate)
    {
        beginDate = truncate(beginDate, 12);
        endDate = truncate(endDate, 12);

        long interval = endDate.getTime() - beginDate.getTime();

        return (int)(interval / 60000L);
    }

    public static long intervalSeconds(Date beginDate, Date endDate)
    {
        if (beginDate.after(endDate)) {
            Date tmp = endDate;
            endDate = beginDate;
            beginDate = tmp;
        }

        long interval = endDate.getTime() - beginDate.getTime();

        return (int)(interval / 1000L);
    }

    public static int getYear(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(1);
    }

    public static int getMonth(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return (calendar.get(2) + 1);
    }

    public static int getDay(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(5);
    }

    public static int getHour(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(10);
    }

    public static int getHourOfDay(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.get(11);
        return day;
    }

    public static Date setHourOfDay(Date date, int amount)
    {
        return DateUtils.setHours(date, amount);
    }

    public static int getMinute(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(12);
    }

    public static Date setMinute(Date date, int amount)
    {
        return DateUtils.setMinutes(date, amount);
    }

    public static int getSecond(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(13);
    }

    public static Date setSecond(Date date, int amount)
    {
        return DateUtils.setSeconds(date, amount);
    }

    public static String format(Date date, String pattern)
    {
        if (StringUtils.isEmpty(pattern))
            pattern = "yyyy-MM-dd HH:mm:ss";

        return DateFormatUtils.format(date, pattern);
    }

    public static String format(String dateString, String pattern, String desPattern)
            throws ParseException
    {
        if (StringUtils.isEmpty(pattern))
            pattern = "yyyy-MM-dd HH:mm:ss";

        Date date = DateUtils.parseDate(dateString, new String[] { pattern });

        return format(date, desPattern);
    }

    public static Date convert(String date, String pattern)
            throws ParseException
    {
        if (StringUtils.isEmpty(pattern))
            pattern = "yyyy-MM-dd HH:mm:ss";

        SimpleDateFormat sdf = new SimpleDateFormat(pattern);

        return sdf.parse(date);
    }

    public static Date parseDate(String dateString)
    {
        try
        {
            return DateUtils.parseDate(dateString, new String[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "HH:mm:ss", "yyyy-MM-dd HH:mm:ss.SSS" });
        }
        catch (ParseException e) {
            throw new InvalidParameterException(dateString + "不是一个正确格式的日期。");
        }
    }

    public static boolean isTimeBetween(Date startTime, Date endTime, Date dateTime)
    {
        return ((((dateTime.equals(startTime)) || (dateTime.after(startTime)))) && (dateTime.before(endTime)));
    }
    /**
     * Method main
     * Description 说明：
     *
     * @param args 说明：
     */
    public static void main(String[] args) {
        System.out.println("args = [" + new Date() + "]");
        System.out.println("args = [" + System.currentTimeMillis() + "]");
        System.out.println("args = [" + new Date() + "]");
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
